package com.kimstore.helper;

import java.io.IOException;
import java.sql.Connection;
import java.util.HashMap;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import com.kimstore.utility.ConfigurationPropertiesUtil;

public class EntityManagerHelper {

	private static EntityManagerFactory entityManagerFactory;
	private static final ThreadLocal<EntityManager> threadLocal;

	private static String driver = ConfigurationPropertiesUtil
			.getProperty("database.driver");
	private static String url = ConfigurationPropertiesUtil
			.getProperty("database.url");
	private static String user = ConfigurationPropertiesUtil
			.getProperty("database.user");
	private static String password = ConfigurationPropertiesUtil
			.getProperty("database.password");;

	static {
		threadLocal = new ThreadLocal<EntityManager>();
		entityManagerFactory = configureEntityManagerFactory();
	}

	public static boolean isOpen() {
		return entityManagerFactory.isOpen();
	}

	public static void closeEntityManagerFactory() {
		if (entityManagerFactory != null)
			entityManagerFactory.close();
	}

	public static EntityManager getEntityManager() {
		EntityManager entityManager = threadLocal.get();

		if (entityManager == null || !entityManager.isOpen()) {
			entityManager = entityManagerFactory.createEntityManager();
			threadLocal.set(entityManager);
		}

		return entityManager;
	}

	public static void closeEntityManager() {
		EntityManager entityManager = threadLocal.get();
		threadLocal.set(null);

		if (entityManager != null)
			entityManager.close();
	}

	public static void beginTransaction() {
		getEntityManager().getTransaction().begin();
	}

	public static void commit() {
		getEntityManager().getTransaction().commit();
	}

	public static EntityManagerFactory configureEntityManagerFactory() {
		try {
			return Persistence.createEntityManagerFactory("persistenceUnit",
					createDatabaseProperties());
		} catch (Throwable e) {
			throw new ExceptionInInitializerError(e);
		}
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private static Map createDatabaseProperties() throws IOException {
		Map databaseProperties = new HashMap();

		databaseProperties.put("javax.persistence.jdbc.driver", driver);
		databaseProperties.put("javax.persistence.jdbc.url", url);
		databaseProperties.put("javax.persistence.jdbc.user", user);

		if (password != null && password != "")
			databaseProperties.put("javax.persistence.jdbc.password", password);

		return databaseProperties;
	}

	public static void refreshPassword(String password) {
		EntityManagerHelper.password = password;
		entityManagerFactory = configureEntityManagerFactory();
		threadLocal.remove();
	}

	@SuppressWarnings("deprecation")
	public static Connection getConnection() {
		return ((org.hibernate.ejb.AbstractEntityManagerImpl) getEntityManager())
				.getSession().connection();
	}

	public static String getPassword() {
		return password;
	}

	public static String getUsername() {
		return user;
	}

	public static String getURL() {
		return url;
	}

}
